home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / xpaint-2.1.1 / arcOp.c < prev    next >
C/C++ Source or Header  |  1995-05-03  |  5KB  |  177 lines

  1. /* +-------------------------------------------------------------------+ */
  2. /* | Copyright 1992, 1993, David Koblas (koblas@netcom.com)            | */
  3. /* |                                                                   | */
  4. /* | Permission to use, copy, modify, and to distribute this software  | */
  5. /* | and its documentation for any purpose is hereby granted without   | */
  6. /* | fee, provided that the above copyright notice appear in all       | */
  7. /* | copies and that both that copyright notice and this permission    | */
  8. /* | notice appear in supporting documentation.  There is no           | */
  9. /* | representations about the suitability of this software for        | */
  10. /* | any purpose.  this software is provided "as is" without express   | */
  11. /* | or implied warranty.                                              | */
  12. /* |                                                                   | */
  13. /* +-------------------------------------------------------------------+ */
  14.  
  15. #include <X11/Intrinsic.h>
  16. #include <X11/StringDefs.h>
  17. #include "xpaint.h"
  18. #include "Paint.h"
  19. #include "misc.h"
  20.  
  21. typedef struct {
  22.     Boolean    lastFlag;
  23.     int    rx, ry, startX, startY, endX, endY, drawn;
  24.     GC    gcx;
  25. } LocalInfo;
  26.  
  27. #define MKRECT(rect, sx, sy, ex, ey, flag) do {                \
  28.     (rect)->x      = MIN(sx, ex);                    \
  29.     (rect)->y      = MIN(sy, ey);                    \
  30.     (rect)->width  = MAX(sx, ex) - (rect)->x;            \
  31.     (rect)->height = MAX(sy, ey) - (rect)->y;            \
  32.     if (flag) {                            \
  33.         (rect)->width = MIN((rect)->width, (rect)->height);    \
  34.         (rect)->height = (rect)->width;             \
  35.         (rect)->x = (ex - sx) < 0 ? sx - (rect)->width : sx;    \
  36.         (rect)->y = (ey - sy) < 0 ? sy - (rect)->width : sy;    \
  37.     }                                \
  38.     if (sx < ex) {                            \
  39.         if (sy < ey) {                        \
  40.             /* +,+ */                    \
  41.             (rect)->x -= (rect)->width;            \
  42.             (rect)->angle1 =   0*64;            \
  43.             (rect)->angle2 =  90*64;            \
  44.         } else {                        \
  45.             /* +,- */                    \
  46.             /* No Change */                    \
  47.             (rect)->angle1 =  90*64;            \
  48.             (rect)->angle2 =  90*64;            \
  49.         }                            \
  50.     } else {                            \
  51.         if (sy < ey) {                        \
  52.             /* -,+ */                    \
  53.             (rect)->x -= (rect)->width;            \
  54.             (rect)->y -= (rect)->height;            \
  55.             (rect)->angle1 =   0*64;            \
  56.             (rect)->angle2 = -90*64;            \
  57.         } else {                        \
  58.             /* -,- */                    \
  59.             (rect)->y -= (rect)->height;            \
  60.             (rect)->angle1 = -90*64;            \
  61.             (rect)->angle2 = -90*64;            \
  62.         }                            \
  63.     }                                \
  64.     (rect)->width *= 2;                        \
  65.     (rect)->height *= 2;                        \
  66.     } while (0)
  67.  
  68. static void    press(Widget w, LocalInfo *l, XButtonEvent *event, OpInfo *info)
  69. {
  70.     /*
  71.     **  Check to make sure all buttons are up, before doing this
  72.     */
  73.     if ((event->state & (Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask)) != 0)
  74.         return;
  75.  
  76.     l->rx   = info->x;
  77.     l->ry   = info->y;
  78.     l->endX = l->startX = event->x;
  79.     l->endY = l->startY = event->y;
  80.  
  81.     l->drawn = False;
  82. }
  83.  
  84.  
  85. static void    motion(Widget w, LocalInfo *l, 
  86.             XMotionEvent *event, OpInfo *info) 
  87. {
  88.     XArc    rect;
  89.  
  90.     if (l->drawn) {
  91.         MKRECT(&rect, l->startX, l->startY, l->endX, l->endY, l->lastFlag);
  92.  
  93.         XDrawArcs(XtDisplay(w), XtWindow(w), l->gcx,
  94.                 &rect, 1);
  95.     }
  96.  
  97.     l->endX = event->x;
  98.     l->endY = event->y;
  99.     l->lastFlag = event->state & ShiftMask;
  100.  
  101.     /*
  102.     **  Really set this flag in the if statement
  103.     */
  104.     if (l->drawn = (l->startX != l->endX && l->startY != l->endY)) {
  105.         MKRECT(&rect, l->startX, l->startY, l->endX, l->endY, l->lastFlag);
  106.  
  107.         XDrawArcs(XtDisplay(w), XtWindow(w), l->gcx,
  108.                 &rect, 1);
  109.     }
  110. }
  111.  
  112. static void    release(Widget w, LocalInfo *l, 
  113.                 XButtonEvent *event, OpInfo *info) 
  114. {
  115.     XArc        rect;
  116.     XRectangle    undo;
  117.     int        mask;
  118.  
  119.     /*
  120.     **  Check to make sure all buttons are up, before doing this
  121.     */
  122.     mask = Button1Mask|Button2Mask|Button3Mask|Button4Mask|Button5Mask;
  123.     switch (event->button) {
  124.     case Button1:    mask ^= Button1Mask; break;
  125.     case Button2:    mask ^= Button2Mask; break;
  126.     case Button3:    mask ^= Button3Mask; break;
  127.     case Button4:    mask ^= Button4Mask; break;
  128.     case Button5:    mask ^= Button5Mask; break;
  129.     }
  130.     if ((event->state & mask) != 0)
  131.         return;
  132.  
  133.     if (l->drawn && info->surface == opWindow)  {
  134.         MKRECT(&rect, l->startX, l->startY, l->endX, l->endY, l->lastFlag);
  135.  
  136.         XDrawArcs(XtDisplay(w), XtWindow(w), l->gcx,
  137.                 &rect, 1);
  138.     }
  139.  
  140.         if (info->surface == opWindow && info->isFat)
  141.         return;
  142.  
  143.     UndoStart(w, info);
  144.  
  145.     MKRECT(&rect, l->rx, l->ry, event->x, event->y, l->lastFlag);
  146.     XDrawArcs(XtDisplay(w), info->drawable, info->first_gc, &rect, 1);
  147.  
  148.     if (info->surface == opPixmap) {
  149.         XYtoRECT(l->rx, l->ry, event->x, event->y, &undo);
  150.         UndoSetRectangle(w, &undo);
  151.         PwUpdate(w, &undo, False);
  152.     }
  153. }
  154.  
  155. /*
  156. **  Those public functions
  157. */
  158. void *ArcAdd(Widget w)
  159. {
  160.     LocalInfo    *l = (LocalInfo*)XtMalloc(sizeof(LocalInfo));
  161.  
  162.     XtVaSetValues(w, XtNcompress, True, NULL);
  163.     OpAddEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
  164.     OpAddEventHandler(w, opWindow, ButtonMotionMask, FALSE, (OpEventProc)motion, l);
  165.     OpAddEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  166.     SetCrossHairCursor(w);
  167.     l->gcx = GetGCX(w);
  168.     return l;
  169. }
  170. void ArcRemove(Widget w, LocalInfo *l)
  171. {
  172.     OpRemoveEventHandler(w, opWindow, ButtonPressMask, FALSE, (OpEventProc)press, l);
  173.     OpRemoveEventHandler(w, opWindow, ButtonMotionMask,FALSE, (OpEventProc)motion, l);
  174.     OpRemoveEventHandler(w, opWindow|opPixmap, ButtonReleaseMask, FALSE, (OpEventProc)release, l);
  175.     XtFree((XtPointer)l);
  176. }
  177.